home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / gcc / ixemulsrc.lha / ixemul-41.4 / library / kern_time.c < prev    next >
C/C++ Source or Header  |  1995-05-28  |  6KB  |  208 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  kern_time.c,v 1.1.1.1 1994/04/04 04:30:41 amiga Exp
  20.  *
  21.  *  kern_time.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:30:41  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  *  Revision 1.1  1992/05/14  19:55:40  mwild
  26.  *  Initial revision
  27.  *
  28.  *
  29.  *  Since the code originated from Berkeley, the following copyright
  30.  *  header applies as well. The code has been changed, it's not the
  31.  *  original Berkeley code!
  32.  */
  33.  
  34. /*
  35.  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
  36.  * All rights reserved.
  37.  *
  38.  * Redistribution is only permitted until one year after the first shipment
  39.  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
  40.  * binary forms are permitted provided that: (1) source distributions retain
  41.  * this entire copyright notice and comment, and (2) distributions including
  42.  * binaries display the following acknowledgement:  This product includes
  43.  * software developed by the University of California, Berkeley and its
  44.  * contributors'' in the documentation or other materials provided with the
  45.  * distribution and in all advertising materials mentioning features or use
  46.  * of this software.  Neither the name of the University nor the names of
  47.  * its contributors may be used to endorse or promote products derived from
  48.  * this software without specific prior written permission.
  49.  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  50.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  51.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  52.  *
  53.  *    @(#)kern_time.c    7.13 (Berkeley) 6/28/90
  54.  */
  55.  
  56. #define KERNEL
  57. #include "ixemul.h"
  58. #include "kprintf.h"
  59.  
  60. #include <sys/time.h>
  61.  
  62. #define err_return(code) \
  63. {                    \
  64.   errno = code;                \
  65.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno)); \
  66.   return errno == 0 ? 0 : -1;        \
  67. }
  68.  
  69. int
  70. getitimer(u_int    which, struct itimerval *itv)
  71. {
  72.   if (which > ITIMER_PROF || !itv)
  73.     err_return (EINVAL);
  74.  
  75.   Disable ();
  76.   *itv = u.u_timer[which];
  77.   Enable();
  78.  
  79.   err_return (0);
  80. }
  81.  
  82. int
  83. setitimer(u_int    which, const struct itimerval *itv, struct itimerval *oitv)
  84. {
  85.     if (which > ITIMER_PROF)
  86.         err_return (EINVAL);
  87.  
  88.     if (oitv && getitimer(which, oitv))
  89.         return -1;
  90.  
  91.     if (itv == 0)
  92.         err_return (0);
  93.  
  94.     if (itimerfix(&itv->it_value) || itimerfix(&itv->it_interval))
  95.         err_return (EINVAL);
  96.  
  97.     Disable ();
  98.     u.u_timer[which] = *itv;
  99.     Enable ();
  100.  
  101.     err_return (0);
  102. }
  103.  
  104. /*
  105.  * Check that a proposed value to load into the .it_value or
  106.  * .it_interval part of an interval timer is acceptable, and
  107.  * fix it to have at least minimal value (i.e. if it is less
  108.  * than the resolution of the clock, round it up.)
  109.  */
  110. itimerfix(struct timeval *tv)
  111. {
  112.  
  113.     if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
  114.         tv->tv_usec < 0 || tv->tv_usec >= 1000000)
  115.         err_return (EINVAL);
  116.     if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < ITIMER_RESOLUTION)
  117.         tv->tv_usec = ITIMER_RESOLUTION;
  118.     err_return (0);
  119. }
  120.  
  121. /*
  122.  * Decrement an interval timer by a specified number
  123.  * of microseconds, which must be less than a second,
  124.  * i.e. < 1000000.  If the timer expires, then reload
  125.  * it.  In this case, carry over (usec - old value) to
  126.  * reducint the value reloaded into the timer so that
  127.  * the timer does not drift.  This routine assumes
  128.  * that it is called in a context where the timers
  129.  * on which it is operating cannot change in value.
  130.  */
  131.  
  132. /* on 0 return, send a signal to process */
  133.  
  134. int
  135. itimerdecr (struct itimerval *itp, int usec)    /* CALLED FROM INTERRUPT !! */
  136. {
  137.   if (itp->it_value.tv_usec < usec) 
  138.     {
  139.       if (itp->it_value.tv_sec == 0) 
  140.     {
  141.       /* expired, and already in next interval */
  142.       usec -= itp->it_value.tv_usec;
  143.       goto expire;
  144.     }
  145.  
  146.       itp->it_value.tv_usec += 1000000;
  147.       itp->it_value.tv_sec--;
  148.     }
  149.  
  150.   itp->it_value.tv_usec -= usec;
  151.   usec = 0;
  152.   if (timerisset(&itp->it_value))
  153.     return (1);
  154.  
  155.   /* expired, exactly at end of interval */
  156. expire:
  157.   if (timerisset(&itp->it_interval)) 
  158.     {
  159.       itp->it_value = itp->it_interval;
  160.       itp->it_value.tv_usec -= usec;
  161.       if (itp->it_value.tv_usec < 0) 
  162.         {
  163.       itp->it_value.tv_usec += 1000000;
  164.       itp->it_value.tv_sec--;
  165.     }
  166.     } 
  167.   else
  168.     itp->it_value.tv_usec = 0;        /* sec is already 0 */
  169.  
  170.   return (0);
  171. }
  172.  
  173. /*
  174.  * Add and subtract routines for timevals.
  175.  * N.B.: subtract routine doesn't deal with
  176.  * results which are before the beginning,
  177.  * it just gets very confused in this case.
  178.  * Caveat emptor.
  179.  */
  180. timevaladd(struct timeval *t1, const struct timeval *t2)
  181. {
  182.  
  183.     t1->tv_sec += t2->tv_sec;
  184.     t1->tv_usec += t2->tv_usec;
  185.     timevalfix(t1);
  186. }
  187.  
  188. timevalsub(struct timeval *t1, const struct timeval *t2)
  189. {
  190.  
  191.     t1->tv_sec -= t2->tv_sec;
  192.     t1->tv_usec -= t2->tv_usec;
  193.     timevalfix(t1);
  194. }
  195.  
  196. timevalfix(struct timeval *t1)
  197. {
  198.  
  199.     if (t1->tv_usec < 0) {
  200.         t1->tv_sec--;
  201.         t1->tv_usec += 1000000;
  202.     }
  203.     if (t1->tv_usec >= 1000000) {
  204.         t1->tv_sec++;
  205.         t1->tv_usec -= 1000000;
  206.     }
  207. }
  208.